package com.crm.smartmachine.ui

import android.os.Bundle
import android.text.TextUtils
import android.view.View
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.NetworkUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.cheng.library.common.clickNoRepeat
import com.cheng.library.common.toast
import com.crm.smartmachine.R
import com.crm.smartmachine.base.SmartBaseFragment
import com.crm.smartmachine.bean.DchWpBean
import com.crm.smartmachine.bean.request.ChwbRequest
import com.crm.smartmachine.bean.request.YCHWPRequest
import com.crm.smartmachine.contants.ActionTypeEnum
import com.crm.smartmachine.contants.EventConstants
import com.crm.smartmachine.databinding.FragmentMainBinding
import com.crm.smartmachine.manager.ModbusManager
import com.crm.smartmachine.manager.callback.WriteRegistersCallback
import com.crm.smartmachine.ui.adapter.HdAdapter
import com.crm.smartmachine.viewmodel.MainViewModel
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.zgkxzx.modbus4And.requset.ModbusParam
import com.zgkxzx.modbus4And.requset.ModbusReq
import com.zgkxzx.modbus4And.requset.OnRequestBack
import net.wimpi.modbus.ModbusCoupler
import net.wimpi.modbus.net.ModbusTCPListener
import net.wimpi.modbus.procimg.SimpleProcessImage
import net.wimpi.modbus.procimg.SimpleRegister
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.net.InetAddress
import java.util.*

class MainFragment : SmartBaseFragment<FragmentMainBinding>(), OnItemClickListener {

    override fun getLayoutId(): Int? = R.layout.fragment_main

//    private val viewModel: MainViewModel by viewModel()

    private val hdAdapter by lazy { HdAdapter() }
    private var spi: SimpleProcessImage? = null
    private var listener: ModbusTCPListener? = null

    // TODO: test 502
    private val port: Int = 1025

    //    private val port: Int = 502
    private val slaveId: Int = 1

    // TODO: test 192.168.3.190
    private val ipAddress by lazy { NetworkUtils.getIPAddress(true) }

    //    private val ipAddress = "192.168.3.190"
    private var isInitModbusReq = false
    private var timer: Timer? = null

    override fun init(savedInstanceState: Bundle?) {
        super.init(savedInstanceState)

        binding.recyclerView.adapter = hdAdapter
        hdAdapter.setOnItemClickListener(this)
        binding.tvIPAddress.text = "IP：$ipAddress, 端口：$port"

        initModbus()
        observe()
        onClick()

        //获取货道
        requestHdData()
        //定时轮询出货单
        startTimer()
    }


    private fun observe() {
        viewModel.defUI.msgEvent.observe(this) {
            when (it.msg) {
                EventConstants.UPDATE_HOME -> { //获取货道
                    requestHdData()
                }
                EventConstants.START_TIMER -> { //轮询出货单
                    ModbusManager.reset() //重置000
                    startTimer()
                }
            }
        }
        viewModel.errorResponse.observe(this) {
            handleErrorResponse(it)
        }
        //货道数据
        viewModel.getHdResponse.observe(this) {
            hdAdapter.setList(it)
        }
        //需要出货的审批单
        viewModel.getChdErrorResponse.observe(this) {
            binding.tvDebugInfo.text = it
        }
        viewModel.getChdResponse.observe(this) {
            cancelTimer()
            showLoadingDialog()
            //待出货list
            val dchList = ArrayList<DchWpBean>()
            //已出货list
            val ychwp = ArrayList<YCHWPRequest>()
            it.slwpList.forEach { wp ->
                //待申领物品在货道里的总库存
                val kcsl = hdAdapter.data.filter { hd ->
                    wp.wpbh == hd.wpbh
                }.sumBy { h ->
                    if (TextUtils.isEmpty(h.kcsl)) 0 else h.kcsl?.toInt() ?: 0
                }
                //申领数量 > 货道库存
                if (wp.slsl.toInt() > kcsl) {
                    toast("${wp.wpmc} 库存不足，无法领取")
                    //接口2，领取失败
                    viewModel.chError(ChwbRequest(it.unid, "0", "N", "库存不足", ychwp))
                } else { //货道库存充足
                    hdAdapter.data.forEach { hd ->
                        if (wp.wpbh == hd.wpbh) {
                            dchList.add(
                                DchWpBean(
                                    hd.bh,
                                    if (TextUtils.isEmpty(hd.kcsl)) 0 else hd.kcsl?.toInt() ?: 0,
                                    wp.wpbh
                                )
                            )
                        }
                    }
                }
            }
            it.slwpList.forEach { wp ->
                dchList.forEach { dch ->
                    if (wp.wpbh == dch.wpbh && wp.slsl.toInt() > 0) {
                        val slsl: String
                        if (wp.slsl.toInt() >= dch.hdsl) {
                            slsl = dch.hdsl.toString()
                            wp.slsl = (wp.slsl.toInt() - dch.hdsl).toString()
                        } else {
                            slsl = wp.slsl
                            wp.slsl = "0"
                        }
                        LogUtils.a("货道${dch.hdbh}领取${slsl}个")
                        ychwp.add(YCHWPRequest(dch.hdbh, dch.wpbh))
                        toast("正在从货道${dch.hdbh}出货${wp.wpmc} ${slsl}个")
                        // 执行出货指令
                        var chuhuoing = true
                        ModbusManager.chuhuo(dch.hdbh, slsl)
                        while (chuhuoing) {
                            ModbusManager.observeChuhuo(object : WriteRegistersCallback {
                                override fun onSuccess() {
                                    chuhuoing = false
                                }
                            })
                            Thread.sleep(4000)
                        }
                    }
                }
            }

            //接口2，领用机出货完毕，通知申请人取货
            LogUtils.d("调接口2")
            hideLoadingDialog()
            viewModel.chwb(ChwbRequest(it.unid, "0", "Y", "", ychwp))
        }
        //领用机出货完毕
        viewModel.chwbResponse.observe(this) {
            //获取货道
            requestHdData()
            // 继续轮询出货单
            startTimer()
        }
    }

    private fun onClick() {
        //领用
        binding.frameReceive.clickNoRepeat {
            XXPermissions.with(activity)
                .permission(Permission.CAMERA)
                .request(object : OnPermissionCallback {
                    override fun onGranted(permissions: MutableList<String>?, all: Boolean) {
                        if (all) {
                            cancelTimer()
                            navigate(R.id.action_mainFragment_to_receiveIndexFragment)
                        } else {
                            toast("请先授予权限:$permissions")
                        }
                    }

                    override fun onDenied(permissions: MutableList<String>?, never: Boolean) {
                        if (never) {
                            toast("授权失败请手动授予权限")
                            XXPermissions.startPermissionActivity(activity, permissions)
                        } else {
                            toast("请先授予权限")
                        }
                    }
                })
        }
        //补货
        binding.frameSupply.clickNoRepeat {
            cancelTimer()
            navigate(R.id.action_mainFragment_to_memberLoginFragment, Bundle().apply {
                putString("action", ActionTypeEnum.SUPPLY.value)
            })
        }
        //存货
        binding.frameSave.clickNoRepeat {
            cancelTimer()
            navigate(R.id.action_mainFragment_to_memberLoginFragment, Bundle().apply {
                putString("action", ActionTypeEnum.SAVE.value)
            })
        }
        //报修
        binding.frameRepair.clickNoRepeat {
            cancelTimer()
            navigate(R.id.action_mainFragment_to_repairIndexFragment)

            // TODO:test
//            val wpList = arrayListOf(
//                TestWpBean("111", "4"),
//                TestWpBean("222", "5"),
//                TestWpBean("333", "3")
//            )
//            val hdList = arrayListOf(
//                TestHdBean("1", "111", "1"),
//                TestHdBean("2", "111", "2"),
//                TestHdBean("3", "111", "3"),
//                TestHdBean("4", "222", "4"),
//                TestHdBean("5", "333", "6")
//            )
//            val dchList = ArrayList<DchWpBean>()
//            wpList.forEach { wp ->
//                val kcsl = hdList.filter { hd ->
//                    wp.wpbh == hd.wpbh
//                }.sumBy {
//                    if (TextUtils.isEmpty(it.kcsl)) 0 else it.kcsl?.toInt() ?: 0
//                }
//                if (wp.slsl.toInt() > kcsl) { //申领数量 > 库存
//                    LogUtils.a("${wp.wpbh} 库存为${kcsl}，无法领取")
//                } else {
//                    hdList.forEach { hd ->
//                        if (wp.wpbh == hd.wpbh) {
//                            dchList.add(
//                                DchWpBean(
//                                    hd.hdbh,
//                                    if (TextUtils.isEmpty(hd.kcsl)) 0 else hd.kcsl?.toInt() ?: 0,
//                                    hd.wpbh
//                                )
//                            )
//                        }
//                    }
//                }
//            }
//            LogUtils.a(dchList)
//            LogUtils.a(wpList)
//            val ychwp = ArrayList<YCHWPRequest>()
//            wpList.forEach { wp ->
//                dchList.forEach { dch ->
//                    if (wp.wpbh == dch.wpbh && wp.slsl.toInt() > 0) {
//                        if (wp.slsl.toInt() >= dch.hdsl) {
//                            ychwp.add(YCHWPRequest(dch.hdbh, dch.wpbh))
//                            LogUtils.a("货道${dch.hdbh}领取${dch.hdsl}个")
//                            wp.slsl = (wp.slsl.toInt() - dch.hdsl).toString()
//                        } else {
//                            ychwp.add(YCHWPRequest(dch.hdbh, dch.wpbh))
//                            LogUtils.a("货道${dch.hdbh}领取${wp.slsl}个")
//                        }
//                    }
//                }
//            }

        }


    }

    override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
//        val list = arrayListOf<Short>(1, 2, 3, 4)
//        if (position == 1) {
//            list.forEach {
//                var chuhuoing = true
//                ModbusReq.getInstance().writeRegisters(object : OnRequestBack<String> {
//                    override fun onSuccess(s: String) {
//                        LogUtils.a("$it 成功：$s")
//                    }
//
//                    override fun onFailed(msg: String) {
//                        toast("$it onFailed:$msg")
//                    }
//                }, Constants.SLAVEID, 0, shortArrayOf(100, 1, it))
//                while (chuhuoing) {
//                    ModbusManager.observeChuhuo(object : WriteRegistersCallback {
//                        override fun onSuccess() {
//                            chuhuoing = false
//                            LogUtils.a("复位了")
//                        }
//                    })
//                    Thread.sleep(4000)
//                }
//            }
//
//            LogUtils.a("for循环完毕")
//        }

//        val bean = this.hdAdapter.data[position]
//        if (position == 11){
//            ModbusManager.chuhuo(bean.wpbh?:"", "1", object :WriteRegistersCallback{
//                override fun onSuccess() {
//                    toast("成功：${bean.mc}")
//                }
//            })
//        } else if (position == 12){
//            ModbusManager.chuhuo(bean.bh, "1", object :WriteRegistersCallback{
//                override fun onSuccess() {
//                    toast("成功：${bean.mc}")
//                }
//            })
//        }else if (position == 13){
//            ModbusManager.chuhuo((position + 1).toString(), "1", object :WriteRegistersCallback{
//                override fun onSuccess() {
//                    toast("成功：${bean.mc}")
//                }
//            })
//        } else {
//
//        }
//        val boxPosition = (position + 1).toShort()
//        ModbusReq.getInstance().writeRegisters(object : OnRequestBack<String> {
//            override fun onSuccess(s: String) {
//                toast("success")
//            }
//
//            override fun onFailed(msg: String) {
//                toast("onFailed:$msg")
//            }
//        }, 1, 0, shortArrayOf(100, boxPosition, 3))
    }

    /**
     * 接口9，获取货道
     */
    private fun requestHdData() {
        viewModel.getHd()
    }

    /**
     * 定时轮询出货单
     */
    private fun startTimer() {
        hideLoadingDialog()
        if (timer == null)
            timer = Timer()
        timer?.schedule(object : TimerTask() {
            override fun run() {
                //接口1，获取需要出货的审批单
                toast("正在查询审批单……")
                viewModel.getChd()
            }
        }, 0, 20000)
    }

    private fun cancelTimer() {
        timer?.cancel()
        timer = null
    }

    private fun initModbus() {
        spi = SimpleProcessImage()
        //保持寄存器
        for (i in 0..100) {
            spi?.addRegister(SimpleRegister(0))
        }
        ModbusCoupler.getReference().processImage = spi
        ModbusCoupler.getReference().isMaster = false
        ModbusCoupler.getReference().unitID = slaveId//从站地址
        Thread {
            val localIp = InetAddress.getByName(ipAddress)
            listener = ModbusTCPListener(3)
            listener?.setPort(port)
            listener?.setAddress(localIp)
            listener?.start()
            if (!isInitModbusReq) {
                initModbusReq()
            }
        }.start()
    }

    private fun initModbusReq() {
        ModbusReq.getInstance()
            .setParam(
                ModbusParam()
                    .setHost(ipAddress) //如:192.168.3.190
                    .setPort(port)
                    .setEncapsulated(false)
                    .setKeepAlive(true)
                    .setTimeout(2000)
                    .setRetries(0)
            )
            .init(object : OnRequestBack<String> {
                override fun onSuccess(p0: String?) {
                    isInitModbusReq = true
                }

                override fun onFailed(p0: String?) {
                    isInitModbusReq = false
                    mActivity.runOnUiThread {
                        toast("初始化失败: $p0")
                    }
                }
            })
    }

    private var loadingDialog: QMUITipDialog? = null

    private fun showLoadingDialog() {
        if (loadingDialog == null) {
            loadingDialog = QMUITipDialog
                .Builder(mContext)
                .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
                .setTipWord("出货中……")
                .create()
        }
        loadingDialog?.show()
    }

    private fun hideLoadingDialog() {
        loadingDialog?.dismiss()
    }

    override fun onDestroy() {
        hideLoadingDialog()
        cancelTimer()
        ModbusReq.getInstance().destory()
        super.onDestroy()
    }

}